package com.example.maruko_course_backend.convertor;

import com.example.maruko_course_backend.utils.StringUtil;
import com.example.maruko_course_backend.vo.KnowledgeItemVo;
import org.h2.util.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class DisplayOrderConvertor {
  
  public static final String DISPLAY_ORDER_WORD = "word";
  public static final String DISPLAY_ORDER_GRAMMAR = "grammar";
  
  public List<String> convert(List<KnowledgeItemVo> wordVos, List<KnowledgeItemVo> grammarVos, String displayOrder) {
    if (StringUtils.isNullOrEmpty(displayOrder)) {
      return convertByVoItemSize(wordVos, grammarVos);
    }
    List<String> displayOrderArr = getDisplayOrderArr(displayOrder);
    return filterDisplayOrderArrBySeq(displayOrderArr, wordVos, grammarVos);
  }
  
  private List<String> filterDisplayOrderArrBySeq(List<String> displayOrderArr, List<KnowledgeItemVo> wordVos, List<KnowledgeItemVo> grammarVos) {
    List<String> filterDisplayOrderByWordVos = filterBySeqAndNoImpactOtherType(displayOrderArr, wordVos, DISPLAY_ORDER_GRAMMAR);
    return filterBySeqAndNoImpactOtherType(filterDisplayOrderByWordVos, grammarVos, DISPLAY_ORDER_WORD);
  }
  
  private List<String> filterBySeqAndNoImpactOtherType(List<String> displayOrderArr, List<KnowledgeItemVo> itemVos, String otherType) {
    if (CollectionUtils.isEmpty(itemVos)) {
      return displayOrderArr.stream().filter(item -> item.equals(otherType)).collect(Collectors.toList());
    }
    List<Integer> keepIndex = itemVos.stream().map(KnowledgeItemVo::getSeq).collect(Collectors.toList());
    return filterByKeepIndexAndNoImpactOther(displayOrderArr, keepIndex, otherType);
  }
  
  private static List<String> filterByKeepIndexAndNoImpactOther(List<String> displayOrderArr, List<Integer> keepIndex, String otherType) {
    List<String> results = new ArrayList<>();
    int currentTypeIndex = 0;
    for (String displayOrder : displayOrderArr) {
      if (displayOrder.equals(otherType)) {
        results.add(displayOrder);
        continue;
      }
      if (keepIndex.contains(currentTypeIndex)) {
        results.add(displayOrder);
      }
      currentTypeIndex++;
    }
    return results;
  }
  
  private static List<String> getDisplayOrderArr(String displayOrder) {
    String[] displayItems = displayOrder.split(StringUtil.COMMA);
    return Arrays.stream(displayItems).collect(Collectors.toList());
  }
  
  private List<String> convertByVoItemSize(List<KnowledgeItemVo> wordVos, List<KnowledgeItemVo> grammarVos) {
    if (CollectionUtils.isEmpty(wordVos) && CollectionUtils.isEmpty(grammarVos)) {
      return new ArrayList<>();
    }
    List<String> displayOrder = new ArrayList<>();
    for (int i = 0; i < wordVos.size(); i++) {
      displayOrder.add(DISPLAY_ORDER_WORD);
    }
    for (int i = 0; i < grammarVos.size(); i++) {
      displayOrder.add(DISPLAY_ORDER_GRAMMAR);
    }
    return displayOrder;
  }
}
